/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * File Name          : app_freertos.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "uart.h"
#include "app_timer.h"
#include "rtc.h"
#include "tim.h"
#include "usart.h"
#include "stm32_hal_legacy.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
uint8_t lpm_work_flag = 0;
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
_B_TIMER_DEF(lpm_timer);
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */

/* USER CODE END Variables */
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
  .name = "defaultTask",
  .priority = (osPriority_t) osPriorityNormal,
  .stack_size = 128 * 4
};
/* Definitions for VoltageTask */
osThreadId_t VoltageTaskHandle;
const osThreadAttr_t VoltageTask_attributes = {
  .name = "VoltageTask",
  .priority = (osPriority_t) osPriorityNormal,
  .stack_size = 128 * 4
};
/* Definitions for ledTask */
osThreadId_t ledTaskHandle;
const osThreadAttr_t ledTask_attributes = {
  .name = "ledTask",
  .priority = (osPriority_t) osPriorityNormal,
  .stack_size = 128 * 4
};
/* Definitions for wakePortTask */
osThreadId_t wakePortTaskHandle;
const osThreadAttr_t wakePortTask_attributes = {
  .name = "wakePortTask",
  .priority = (osPriority_t) osPriorityNormal,
  .stack_size = 128 * 4
};

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
void lpm_enable();
/* USER CODE END FunctionPrototypes */

void StartDefaultTask(void *argument);
void StartVoltageTask(void *argument);
void StartTaskLed(void *argument);
void StartTaskWakePort(void *argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/**
  * @brief  FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */

  /* Create the thread(s) */
  /* creation of defaultTask */
  defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);

  /* creation of VoltageTask */
  VoltageTaskHandle = osThreadNew(StartVoltageTask, NULL, &VoltageTask_attributes);

  /* creation of ledTask */
  ledTaskHandle = osThreadNew(StartTaskLed, NULL, &ledTask_attributes);

  /* creation of wakePortTask */
  wakePortTaskHandle = osThreadNew(StartTaskWakePort, NULL, &wakePortTask_attributes);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */

  /* USER CODE BEGIN RTOS_EVENTS */
  /* add events, ... */
  /* USER CODE END RTOS_EVENTS */

}

/* USER CODE BEGIN Header_StartDefaultTask */
/**
  * @brief  Function implementing the defaultTask thread.
  * @param  argument: Not used
  * @retval None
  */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN StartDefaultTask */
  /* Infinite loop */
  uint8_t buf[20] = {0};
  uint16_t len = 0;
  for(;;)
  {
    len = module_uart_receive_process(buf);
    if(len != 0)
    {
       printf("the str you put is:%s\r\n",buf);
    }
    osDelay(20);
  }
  /* USER CODE END StartDefaultTask */
}

/* USER CODE BEGIN Header_StartVoltageTask */
/**
* @brief Function implementing the VoltageTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartVoltageTask */
void StartVoltageTask(void *argument)
{
  /* USER CODE BEGIN StartVoltageTask */
  /* Infinite loop */
  for(;;)
  {
    osDelay(10);
  }
  /* USER CODE END StartVoltageTask */
}

/* USER CODE BEGIN Header_StartTaskLed */
/**
* @brief Function implementing the ledTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTaskLed */
void StartTaskLed(void *argument)
{
  /* USER CODE BEGIN StartTaskLed */
  /* Infinite loop */
  for(;;)
  {
    osDelay(10);
  }
  /* USER CODE END StartTaskLed */
}

/* USER CODE BEGIN Header_StartTaskWakePort */
/**
* @brief Function implementing the wakePortTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTaskWakePort */
void StartTaskWakePort(void *argument)
{
  /* USER CODE BEGIN StartTaskWakePort */
   b_timer_create(&lpm_timer,B_TIMER_MODE_SINGLE_SHOT,lpm_enable);
  /* Infinite loop */
  for(;;)
  {
     if(module_uart_receive_running() != true)
     {
       b_timer_start(&lpm_timer,5000);//串口停止接收5s进入低功耗
       b_timer_reload(&lpm_timer,5000);//串口停止接收5s进入低功耗
     }
     else{
       b_timer_stop(&lpm_timer);
     }

    if(lpm_work_flag == 1)
    {
      Set_Stop2Mode();
    }
    osDelay(10);
  }
  /* USER CODE END StartTaskWakePort */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
void lpm_enable()
{
  lpm_work_flag = 1;
}

void Set_Stop2Mode(void)
{
	//把所有开启的外设先失能，再把引脚设为模拟输入或者浮空输入，需要上拉的就继续保持上拉
	HAL_GPIO_DeInit(GPIOB,LED1_Pin|LED2_Pin|LED3_Pin);

	HAL_TIM_Base_Stop(&htim2);
	__HAL_RCC_TIM2_CLK_DISABLE();
	
	HAL_UART_DeInit(&huart1);
	__HAL_RCC_USART1_CLK_DISABLE();

	__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); //清除唤醒标志
	HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);	//设置WAKEUP用于唤醒
	HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 1, RTC_WAKEUPCLOCK_CK_SPRE_16BITS,0);//RTC时钟50秒唤醒一次

	SysTick->CTRL = 0x00;//关闭定时器
    SysTick->VAL = 0x00;//清空val,清空定时器
    lpm_work_flag = 0;

	HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);//进入STOP2
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	SystemClock_Config();
	MX_GPIO_Init();
	MX_DMA_Init();
	MX_ADC_Init();
	MX_RTC_Init();
	MX_USART1_UART_Init();
	MX_TIM2_Init();
	__HAL_RCC_TIM2_CLK_ENABLE();
	module_uart_init();
	printf("push_botton wakeup:\r\n");
}

void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{   
	SystemClock_Config();
	MX_GPIO_Init();
	MX_DMA_Init();
	MX_ADC_Init();
	MX_RTC_Init();
	MX_USART1_UART_Init();
	MX_TIM2_Init();
	__HAL_RCC_TIM2_CLK_ENABLE();
	module_uart_init();
	printf("rtc wakeup:\r\n");
}

/* USER CODE END Application */
